package com.lyuewei.ringtone;

import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.media.AudioManager;
import android.net.Uri;
import android.os.Handler;
import android.os.Looper;
import android.os.PowerManager;
import android.provider.CallLog;
import android.telephony.TelephonyManager;
import com.elvishew.xlog.XLog;
import com.lyuewei.ringtone.data.AppDatabase;
import com.lyuewei.ringtone.data.RingerSetting;
import com.lyuewei.ringtone.data.RingerSettingDao;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class IncomingCallReceiver extends BroadcastReceiver {

    private AudioManager audioManager;
    private int originalRingerMode=-1;
    private int originalRingerVolume=-1;
    private final Handler handler = new Handler(Looper.getMainLooper());
    private RingerSettingDao ringerSettingDao;
    private Context context;
    private int originalNotificationFilter = -1; // 保存原始的勿扰模式过滤状态
    private NotificationManager notificationManager; // 添加 NotificationManager 成员变量
    private final ExecutorService databaseReadExecutor =
            Executors.newSingleThreadExecutor();
    @Override
    public void onReceive(Context context, Intent intent) {
        XLog.d("收到电话状态变更广播");
        this.context = context;
        if (intent.getAction() != null && intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) {
            String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
            XLog.d("电话状态变更: " + state);
            if (TelephonyManager.EXTRA_STATE_IDLE.equals(state) || TelephonyManager.EXTRA_STATE_OFFHOOK.equals(state)) {
                // 通话结束或接通时，恢复音量并停止铃声
                XLog.d("通话结束或接听，恢复音量");
                handler.postDelayed(() -> {
                    XLog.d("延迟恢复音量");
                    restoreVolume();
                }, 500);
                return;
            }
            if (!isDeviceLocked()) {
                XLog.d("设备未被锁定。不强制铃声。");
                return;
            }
            // 获取 RingerSettingDao 实例
            if (ringerSettingDao == null) {
                AppDatabase database = MyApplication.getDatabase(); // 获取数据库实例
                ringerSettingDao = database.ringerSettingDao();
            }

            // 延长 BroadcastReceiver 的生命周期
            final PendingResult pendingResult = goAsync();
            // 在后台线程中执行数据库查询
            databaseReadExecutor.execute(() -> {
            String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
            if (incomingNumber == null || incomingNumber.isEmpty()) {
                // 如果直接获取不到，尝试从通话记录中获取
                // 需要 READ_CALL_LOG 权限
                XLog.d("无法直接获取到来电号码。尝试从通话记录中获取.");
                incomingNumber = getIncomingNumberFromCallLog();
            }
            XLog.d("呼入号码: " + incomingNumber);
                RingerSetting setting= getRingerSetting(incomingNumber);
                if (setting!=null) {
                    if (isWithRinger(incomingNumber,setting)) {
                        XLog.d("号码(" + incomingNumber + ") 正在来电。强制响铃。");
                        forceRingtone(setting);
                    }
            } else if (incomingNumber != null) {
                XLog.d("来电号码 (" + incomingNumber + ") 没有进行配置.");
            } else {
                XLog.d("获取不到来电号码 .");
            }
                pendingResult.finish();
        });
        }
    }

    /**根据规矩判断是否需要响铃*/
    private boolean isWithRinger(String incomingNumber, RingerSetting setting){
       // 获取通话记录判断是否需要响铃,判断是否在时间范围内
        if (setting!=null) {
            if (!setting.isCurrentTimeInRange()){
                XLog.d("不在时间范围内，不响铃");
                return false;
            }
            XLog.d("号码 (" + incomingNumber + ") 配置: " + setting.getName()+" "+setting.getPhone());
            if ( setting.getInterval() <= 0 || setting.getTimes() <= 0) {
                //间隔或次数小于等于0，进行响铃
                return true;
            }else {
                int missedCallCount = getMissedCallCountInTimeRange(
                        incomingNumber,
                        setting.getInterval());
                if (missedCallCount == -1) {
                    XLog.w( "获取通话记录失败，不进行响铃");
                    return false;
                }
                // 判断是否需要响铃：未接电话数小于设定的次数
                boolean shouldRing = missedCallCount >= setting.getTimes();
                XLog.d("检测响铃: 电话=" + incomingNumber+
                        ", 未接来电数=" + missedCallCount +
                        ", 配置来电数=" + setting.getTimes() +
                        ", 配置来电间隔=" + setting.getInterval() + "分" +
                        ", 是否响铃=" + shouldRing);

                return shouldRing;
            }
        }
        return false;

    }

    /**获取响铃配置*/
    private RingerSetting getRingerSetting(String incomingNumber){
        RingerSetting setting=null;
        if (incomingNumber != null && !incomingNumber.isEmpty()) {
            setting = ringerSettingDao.findEnabledByPhone(incomingNumber);
            if (setting == null){
                XLog.d("号码 (" + incomingNumber + ") 没有进行配置或配置未开启.");
                setting = ringerSettingDao.findEnabledByGlobal();
            }
        }else{
            XLog.d("号码为空,不进行处理.");
        }
        XLog.d("找到设置: " + setting);
        return setting;
    }

    /**
     * 检查设备是否处于锁屏状态。
     */
    private boolean isDeviceLocked() {
        KeyguardManager keyguardManager = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
        if (keyguardManager == null) {
            XLog.e("KeyguardManager is null.");
            return false; // 无法获取 KeyguardManager，假设未锁屏
        }
        // isKeyguardLocked() 检查设备是否处于锁屏状态（显示锁屏界面）
        // isDeviceLocked() 检查设备是否已锁定（包括显示密码/图案/指纹等解锁界面）
        // 通常使用 isDeviceLocked() 更可靠

        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        boolean isScreenOn = powerManager != null && powerManager.isInteractive();
        return keyguardManager.isDeviceLocked()||!isScreenOn;
    }

    /**
     * 在通话记录中找到来电号码
     */
    private String getIncomingNumberFromCallLog() {
        if (context.checkSelfPermission(android.Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
            // 如果没有 READ_CALL_LOG 权限，无法查询通话记录
            XLog.w("没有授权READ_CALL_LOG 权限.");
            return null;
        }

        String incomingNumber = null;
        try (Cursor cursor = context.getContentResolver().query(
                CallLog.Calls.CONTENT_URI,
                new String[]{CallLog.Calls.NUMBER}, // 只查询号码列，提高效率
                null,
                null,
                CallLog.Calls.DATE + " DESC LIMIT 1" // 查询最近一条记录
        )) {

            if (cursor != null && cursor.moveToFirst()) {
                int numberIndex = cursor.getColumnIndex(CallLog.Calls.NUMBER);
                if (numberIndex != -1) {
                    incomingNumber = cursor.getString(numberIndex);
                    XLog.d("在通话记录中找到号码: " + incomingNumber);
                } else {
                    XLog.w( "没有找到 CallLog.Calls.NUMBER .");
                }
            } else {
                XLog.d("没有通话记录。");
            }
        } catch (Exception e) {
            XLog.e("读取通话记录失败: " + e.getMessage());
        }
        return incomingNumber;
    }

    /**
     * 当前是否是响铃模式
     */
    private boolean isRingerNormalMode() {
        initAudioManager();
        if (audioManager == null) {
            XLog.e("AudioManager is null.");
            return false;
        }
        int ringerMode = audioManager.getRingerMode();
        return ringerMode == AudioManager.RINGER_MODE_NORMAL;
    }

    /**
     * 强制播放铃声
     */
    private void forceRingtone(RingerSetting setting) {
        initAudioManager();
        if (isRingerNormalMode()) {
            XLog.d("当前模式为响铃模式。不处理。");
            return;
        }
        if (audioManager == null) {
            XLog.e("AudioManager is null.");
            return;
        }
        // 检查并保存原始的勿扰模式过滤状态
        if (notificationManager != null && notificationManager.isNotificationPolicyAccessGranted()) {
            originalNotificationFilter = notificationManager.getCurrentInterruptionFilter();

            XLog.d("原来勿扰模式过滤状态: " + originalNotificationFilter);
        } else {
            XLog.w("没有勿扰模式权限或 NotificationManager 为空，无法保存勿扰模式状态。");
            originalNotificationFilter = -1; // 标记为无法获取
        }
        // 保存原始铃声模式
        originalRingerMode = audioManager.getRingerMode();
       originalRingerVolume= audioManager.getStreamVolume(AudioManager.STREAM_RING);
       saveRingerModeAndVolume(originalRingerMode,originalRingerVolume,originalNotificationFilter);
        XLog.d("原来模式为: " + ringerModeName(originalRingerMode));
        XLog.d("原来音量为: " + originalRingerMode);
        // 将设备设置为正常模式并设置铃声音量
        audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
        int maxVolume = audioManager.getStreamMaxVolume(AudioManager.STREAM_RING);
        int volume=setting.getVolume()*maxVolume/100;
        XLog.d("音量: " + volume);
        audioManager.setStreamVolume(AudioManager.STREAM_RING, volume, 0);
    }


    /**
     * 恢复音量并停止铃声
     */
    @SuppressLint("WrongConstant")
    private void restoreVolume() {
        initAudioManager();
        restoreRingerModeAndVolume();
        if (audioManager != null) {

            // 恢复到对应模式。
            if(originalRingerMode>-1) {
                audioManager.setStreamVolume(AudioManager.STREAM_RING, originalRingerVolume, 0);
                XLog.d("恢复到之前铃声模式: " + ringerModeName(originalRingerMode));
            }
            if (originalRingerVolume > -1) {
                audioManager.setRingerMode(originalRingerMode);
                XLog.d("恢复到之前铃声音量: " + originalRingerVolume);
            }

        }
        // 恢复原始的勿扰模式过滤状态
        if (notificationManager != null && notificationManager.isNotificationPolicyAccessGranted() ) {
            try {
                // 尝试恢复原始过滤状态
                if (originalNotificationFilter > -1) {
                    notificationManager.setInterruptionFilter(originalNotificationFilter);
                    XLog.d("恢复到之前勿扰模式过滤状态: " + originalNotificationFilter);
                }/* else {
                    // 如果没有保存的原始状态，或者恢复后仍然有问题，强制设置为允许所有中断
                    notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
                    XLog.d( "没有保存的原始勿扰模式状态或恢复有问题，强制将勿扰模式设置为允许所有中断.");
                }*/
            } catch (SecurityException e) {
                XLog.e( "没有权限恢复勿扰模式状态", e);
                // 这不应该发生，因为之前检查了权限，但以防万一
            }
        } else {
            // 如果无法恢复原始勿扰模式状态 (例如没有权限或没有保存)，
            // 你可以考虑在这里设置一个默认的行为，
            // 例如，如果原始模式是静音或震动，恢复到允许所有中断，
            // 以避免来电结束后设备仍然静音的情况（如果不是用户自己设置的静音）
            XLog.w( "无法恢复勿扰模式状态，根据原始铃声模式尝试设置默认勿扰模式.");
            if (originalRingerMode == AudioManager.RINGER_MODE_SILENT || originalRingerMode == AudioManager.RINGER_MODE_VIBRATE) {
                // 如果原始是静音或震动，恢复时确保可以接收通知
                if (notificationManager != null && notificationManager.isNotificationPolicyAccessGranted()) {
                    try {
                        notificationManager.setInterruptionFilter(NotificationManager.INTERRUPTION_FILTER_ALL);
                        XLog.d( "将勿扰模式设置为允许所有中断.");
                    } catch (SecurityException e) {
                        XLog.e( "没有权限设置勿扰模式为允许所有中断", e);
                    }
                }
            }
        }
        // 移除可能存在的延迟停止任务
        handler.removeCallbacksAndMessages(null);
    }


    private void initAudioManager() {
        if (audioManager == null) {
            audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
        }
        if (notificationManager == null) {
            notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
        }
    }
    private String ringerModeName(int mode) {
        switch (mode) {
            case AudioManager.RINGER_MODE_SILENT:
                return "静音模式";
            case AudioManager.RINGER_MODE_VIBRATE:
                return "震动模式";
            case AudioManager.RINGER_MODE_NORMAL:
                return "正常模式";
            default:
                return "未知模式";
        }
    }
    /**
     * 获取某个号码在过去指定时间内的未接电话记录数。
     *
     * @param phoneNumber 要查询的电话号码
     * @param timeRangeMinute 时间范围（分）
     * @return 未接电话记录数，如果发生错误或没有权限则返回 -1
     */
    public  int getMissedCallCountInTimeRange( String phoneNumber, long timeRangeMinute) {
        if ( phoneNumber == null || phoneNumber.isEmpty()) {
            XLog.e("号码无效");
            return -1;
        }

        // 检查是否拥有读取通话记录的权限
        if (context.checkSelfPermission(android.Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
            XLog.w( "没有读取通话记录权限.");
            return -1;
        }

        int missedCallCount = 0;
        long tenMinutesAgo = System.currentTimeMillis() - (timeRangeMinute*60000);

        // 查询条件
        String selection = CallLog.Calls.TYPE + " = ? AND " +
                CallLog.Calls.NUMBER + " = ? AND " +
                CallLog.Calls.DATE + " > ?";

        String[] selectionArgs = new String[] {
                String.valueOf(CallLog.Calls.MISSED_TYPE), // 未接电话类型
                phoneNumber,                               // 特定号码
                String.valueOf(tenMinutesAgo)              // 在过去 timeRangeMillis 毫秒内
        };

        // 查询列 (我们只需要计数，所以查询 _ID 就够了，或者不查询任何列)
        String[] projection = new String[] { CallLog.Calls._ID }; // 只查询 ID 列

        Uri callLogUri = CallLog.Calls.CONTENT_URI;

        try (Cursor cursor = context.getContentResolver().query(
                callLogUri,
                projection,
                selection,
                selectionArgs,
                null // 不需要排序
        )) {

            if (cursor != null) {
                missedCallCount = cursor.getCount(); // 获取符合条件的记录数
                XLog.d("在最近"+timeRangeMinute+"分钟内有 " + missedCallCount + " 个未接电话来自 " + phoneNumber );
            } else {
                XLog.d("没有查询到记录.");
            }

        } catch (SecurityException e) {
            XLog.e("权限问题或其他安全异常", e);
            missedCallCount = -1;
        } catch (Exception e) {
            XLog.e("查询通话记录错误.", e);
            missedCallCount = -1;
        }
        return missedCallCount;
    }

    private void saveRingerModeAndVolume(int mode, int volume, int notificationFilter) {
        SharedPreferences preferences = context.getSharedPreferences("ringer_mode_and_volume", Context.MODE_PRIVATE);
        preferences.edit()
                .putInt("mode", mode)
                .putInt("volume", volume).putInt("notification_filter", notificationFilter)
                .putLong("last_update", System.currentTimeMillis())
                .apply();
        XLog.d("保存模式: " + ringerModeName(mode) + ", 音量: " + volume + ", 勿扰模式过滤状态: " + notificationFilter);
    }
    private void restoreRingerModeAndVolume() {
        SharedPreferences preferences = context.getSharedPreferences("ringer_mode_and_volume", Context.MODE_PRIVATE);
        int mode = preferences.getInt("mode", -1);
        int volume = preferences.getInt("volume", -1);
        int notificationFilter = preferences.getInt("notification_filter", -1);
        long lastUpdate = preferences.getLong("last_update", 0);
        if ((System.currentTimeMillis() - lastUpdate) <= (60 * 1000)) {
           originalRingerVolume= volume;
           originalRingerMode= mode;
           originalNotificationFilter= notificationFilter;
            XLog.d("从 SharedPreferences 恢复模式: " + ringerModeName(mode) + ", 音量: " + volume + ", 勿扰模式过滤状态: " + notificationFilter);
        }else {
            XLog.d( "SharedPreferences 中的恢复数据已过期或不存在.");
            originalRingerVolume = -1;
            originalRingerMode = -1;
            originalNotificationFilter = -1;
        }
        preferences.edit().clear().apply();
    }



}

